home *** CD-ROM | disk | FTP | other *** search
- /* Copyright (c) 1992 The Geometry Center; University of Minnesota
- 1300 South Second Street; Minneapolis, MN 55454, USA;
-
- This file is part of geomview/OOGL. geomview/OOGL is free software;
- you can redistribute it and/or modify it only under the terms given in
- the file COPYING, which you should have received along with this file.
- This and other related software may be obtained via anonymous ftp from
- geom.umn.edu; email: software@geom.umn.edu. */
- static char *copyright = "Copyright (C) 1992 The Geometry Center";
-
- /* Authors: Charlie Gunn, Pat Hanrahan, Stuart Levy, Tamara Munzner, Mark Phillips, Celeste Fowler */
-
- /*
- ** point3.c - 3D vector arithmetic module.
- **
- ** pat hanrahan
- **
- */
- # include <math.h>
- # include "tolerance.h"
- # include "point3.h"
- # include "transform3.h"
-
- Point3 Pt3Origin = { 0., 0., 0. };
-
- /* print vector */
- void
- Pt3Print( const Point3 *v )
- {
- /* Only works if Pt3Coord is a float */
- printf("[%g %g %g]\n", v->x, v->y, v->z);
- }
-
- void
- Pt3From(Point3 *v, double x, double y, double z)
- {
- v->x = x;
- v->y = y;
- v->z = z;
- }
-
- /* v2 = v1 */
- void
- Pt3Copy( const Point3 *v1, Point3 *v2 )
- {
- v2->x = v1->x;
- v2->y = v1->y;
- v2->z = v1->z;
- }
-
- /* v3 = v1 + v2 */
- void
- Pt3Add( const Point3 *v1, const Point3 *v2, Point3 *v3 )
- {
- v3->x = v1->x + v2->x;
- v3->y = v1->y + v2->y;
- v3->z = v1->z + v2->z;
- }
-
- /* v3 = v1 - v2 */
- void
- Pt3Sub( const Point3 *v1, const Point3 *v2, Point3 *v3)
- {
- v3->x = v1->x - v2->x;
- v3->y = v1->y - v2->y;
- v3->z = v1->z - v2->z;
- }
-
- /* v2 = s * v1 */
- void
- Pt3Mul( double s, const Point3 *v1, Point3 *v2 )
- {
- v2->x = s*v1->x;
- v2->y = s*v1->y;
- v2->z = s*v1->z;
- }
-
-
- /* v1 . v2 */
- Pt3Coord
- Pt3Dot( const Point3 *v1, const Point3 *v2 )
- {
- return v1->x*v2->x+v1->y*v2->y+v1->z*v2->z;
- }
-
- /* v3 = v1 x v2 */
- void
- Pt3Cross( const Point3 *v1, const Point3 *v2, Point3 *v3 )
- {
- v3->x = v1->y*v2->z-v1->z*v2->y;
- v3->y = v1->z*v2->x-v1->x*v2->z;
- v3->z = v1->x*v2->y-v1->y*v2->x;
- }
-
- /* v1 . (v2 x v3) */
- Pt3Coord
- Pt3TripleDot( const Point3 *v1, const Point3 *v2, const Point3 *v3 )
- {
- return v1->x*(v2->y*v3->z-v2->z*v3->y)
- + v1->y*(v2->z*v3->x-v2->x*v3->z)
- + v1->z*(v2->x*v3->y-v2->y*v3->x);
- }
-
- /* v4 = (v1 x v2) x v3 */
- void
- Pt3TripleCross( const Point3 *v1, const Point3 *v2, const Point3 *v3, Point3 *v4 )
- {
- Point3 v;
-
- Pt3Cross( v1, v2, &v );
- Pt3Cross( &v, v3, v4 );
- }
-
- Pt3Coord
- Pt3Length( const Point3 *v )
- {
- return sqrt( v->x*v->x + v->y*v->y + v->z*v->z );
- }
-
- Pt3Coord
- Pt3Distance( const Point3 *v1, const Point3 *v2 )
- {
- Point3 v12;
-
- Pt3Sub(v1,v2,&v12);
-
- return Pt3Length(&v12);
- }
-
- Pt3Coord
- Pt3Angle( const Point3 *v1, const Point3 *v2 )
- {
-
- return(acos(Pt3Dot(v1, v2) / (Pt3Length(v1) * Pt3Length(v2))));
-
- }
-
- void
- Pt3Unit( Point3 *v )
- {
- Pt3Coord len;
-
- len = Pt3Length(v);
- if( len != 0. && len != 1. )
- Pt3Mul( 1./len, v, v );
- }
-
-
- /*
- * lerp - linear interpolation
- *
- * v3 = (1-t)*v1 + t*v2
- */
- void
- Pt3Lerp( double t, const Point3 *v1, const Point3 *v2, Point3 *v3 )
- {
- v3->x = (1.-t)*v1->x + t*v2->x;
- v3->y = (1.-t)*v1->y + t*v2->y;
- v3->z = (1.-t)*v1->z + t*v2->z;
- }
-
- void
- Pt3Comb( double t1, const Point3 *v1, double t2, const Point3 *v2, Point3 *v3 )
- {
- v3->x = t1*v1->x + t2*v2->x;
- v3->y = t1*v1->y + t2*v2->y;
- v3->z = t1*v1->z + t2*v2->z;
- }
-
-
- /* vectors equal */
- int
- Pt3Equal( const Point3 *v1, const Point3 *v2 )
- {
- Pt3Coord v;
-
- v = Pt3Distance(v1, v2);
-
- return fz(v);
- }
-
- /* parallel vectors */
- int
- Pt3Parallel( const Point3 *v1, const Point3 *v2 )
- {
- Point3 v3;
- Pt3Coord v;
-
- Pt3Cross(v1,v2,&v3);
- v=Pt3Length(&v3);
-
- return fz(v);
- }
-
- /* perpendicular vectors */
- int
- Pt3Perpendicular( const Point3 *v1, const Point3 *v2 )
- {
- Pt3Coord v;
-
- v=Pt3Dot(v1,v2);
-
- return fz(v);
- }
-
- void
- Pt3Transform( T, p1, p2 )
- Transform3 T;
- Point3 *p1, *p2;
- {
- register Pt3Coord x, y, z, w;
-
- x = p1->x;
- y = p1->y;
- z = p1->z;
- w = (T[X][W]*x + T[Y][W]*y + T[Z][W]*z + T[W][W]);
- if(w != 1.0) {
- w = 1.0 / w;
- p2->x = w * (x*T[X][X] + y*T[Y][X] + z*T[Z][X] + T[W][X]);
- p2->y = w * (x*T[X][Y] + y*T[Y][Y] + z*T[Z][Y] + T[W][Y]);
- p2->z = w * (x*T[X][Z] + y*T[Y][Z] + z*T[Z][Z] + T[W][Z]);
- } else {
- p2->x = x*T[X][X] + y*T[Y][X] + z*T[Z][X] + T[W][X];
- p2->y = x*T[X][Y] + y*T[Y][Y] + z*T[Z][Y] + T[W][Y];
- p2->z = x*T[X][Z] + y*T[Y][Z] + z*T[Z][Z] + T[W][Z];
- }
- }
-
- void
- Pt3TransformN( T, p1, p2, n )
- Transform3 T;
- Point3 *p1, *p2;
- int n;
- {
- while( n-- )
- Pt3Transform( T, p1++, p2++ );
- }
-
- void
- NormalTransform( T, a, b )
- Transform3 T;
- Point3 *a, *b;
- {
- Pt3Transform(T, a, b);
- b->x -= T[W][X];
- b->y -= T[W][Y];
- b->z -= T[W][Z];
- Pt3Unit(b);
- }
-
- void
- NormalTransformN( T, a, b, n )
- Transform3 T;
- Point3 *a, *b;
- int n;
- {
- while ( n-- )
- NormalTransform( T, a++, b++ );
- }
-